package pers.sloera.leetcode.editor.cn;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 最好的扑克手牌
 *
 * @author sloera
 * @date 2023-02-20 22:15:46
 */
class BestPokerHand {
    public static void main(String[] args) {
        Solution solution = new BestPokerHand().new Solution();
        System.out.println(solution.bestHand(new int[]{13, 2, 3, 1, 9}, new char[]{'a', 'a', 'a', 'a', 'a'}));
        System.out.println(solution.bestHand(new int[]{4, 4, 2, 4, 4}, new char[]{'d', 'a', 'a', 'b', 'c'}));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public String bestHand(int[] ranks, char[] suits) {
            return HandType.forEachCountryEnum(ranks, suits);
        }
    }

    enum HandType {
        /**
         * 同花
         */
        FLUSH("Flush", (ranks, suits) -> {
            return String.valueOf(suits).chars().boxed().collect(Collectors.groupingBy(x -> x)).size() == 1;
        }), KIND("Three of a Kind", (ranks, suits) -> {
            return Arrays.stream(ranks).boxed().collect(Collectors.groupingBy(x -> x, Collectors.counting())).values().stream().anyMatch(count -> count >= 3);
        }), PAIR("Pair", (ranks, suits) -> {
            return Arrays.stream(ranks).boxed().collect(Collectors.groupingBy(x -> x, Collectors.counting())).values().stream().anyMatch(count -> count == 2);
        }), HIGH("High Card", (ranks, suits) -> {
            return Arrays.stream(ranks).boxed().collect(Collectors.groupingBy(x -> x)).size() == 5;
        });
        private final String type;
        private final Function<int[], char[], Boolean> isMatch;

        HandType(String type, Function<int[], char[], Boolean> isMatch) {
            this.type = type;
            this.isMatch = isMatch;
        }

        public String getType() {
            return type;
        }

        public static String forEachCountryEnum(int[] ranks, char[] suits) {
            return Arrays.stream(HandType.values()).filter(handType -> handType.isMatch.apply(ranks, suits)).findFirst().orElse(null).getType();
        }
    }

    @FunctionalInterface
    interface Function<A, B, R> {
        //R is like Return, but doesn't have to be last in the list nor named R.
        public R apply(A a, B b);
    }
    //leetcode submit region end(Prohibit modification and deletion)

}
